package utils

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"
)

// 获取本周、本月、本年的时间范围
func GetTimeRange(rangeType string) (startTime, endTime time.Time, err error) {
	// 获取当前时间
	now := time.Now()

	// 保证返回的时间时分秒纳秒归零
	zeroTime := func(t time.Time) time.Time {
		return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
	}

	// 判断 rangeType 参数并返回对应的时间范围
	switch rangeType {
	case "week":
		// 计算本周周一的日期
		weekday := now.Weekday()
		offset := (int(weekday) - 1 + 7) % 7    // 计算当前日期到周一的差值，+7是为了处理周日（0号）的情况
		weekStart := now.AddDate(0, 0, -offset) // 本周周一的日期
		weekEnd := weekStart.AddDate(0, 0, 7)   // 本周的最后一天（周日）+1天

		return zeroTime(weekStart), zeroTime(weekEnd), nil

	case "month":
		// 本月的开始时间和结束时间（结束时间+1天）
		monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) // 本月的第一天
		monthEnd := monthStart.AddDate(0, 1, 0)                                         // 下个月的第一天，减去1秒就是本月最后一秒
		return zeroTime(monthStart), zeroTime(monthEnd), nil

	case "year":
		// 本年的开始时间和结束时间（结束时间+1天）
		yearStart := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location()) // 本年的第一天
		yearEnd := yearStart.AddDate(1, 0, 0)                                // 明年第一天，减去1秒就是本年最后一秒
		return zeroTime(yearStart), zeroTime(yearEnd), nil

	default:
		return time.Time{}, time.Time{}, errors.New("invalid range type")
	}
}

// LogRetentionWindow 解析日志保留时间窗口
// 支持格式：
// - 3d（3天）
// - 1w（1周）
// - 1m（1月）
// - 1y（1年）
// - 1645601695-1737601695（自定义时间段，前后两个时间戳）
// ParseLogRetentionWindow 解析日志保留时间窗口
func ParseLogRetentionWindow(logRetentionWindow string) (startTime, endTime time.Time, err error) {
	// 获取当前时间的 0 点
	now := time.Now()
	todayMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())

	// 默认结束时间为下一天的 0 点
	endTime = todayMidnight.Add(24 * time.Hour)

	// 解析不同的格式
	switch {
	case strings.HasSuffix(logRetentionWindow, "d"): // 天
		days, err := strconv.Atoi(strings.TrimSuffix(logRetentionWindow, "d"))
		if err != nil {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid days format: %v", err)
		}
		startTime = endTime.Add(-time.Duration(days) * 24 * time.Hour)

	case strings.HasSuffix(logRetentionWindow, "w"): // 周
		weeks, err := strconv.Atoi(strings.TrimSuffix(logRetentionWindow, "w"))
		if err != nil {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid weeks format: %v", err)
		}
		startTime = endTime.Add(-time.Duration(weeks) * 7 * 24 * time.Hour)

	case strings.HasSuffix(logRetentionWindow, "m"): // 月
		months, err := strconv.Atoi(strings.TrimSuffix(logRetentionWindow, "m"))
		if err != nil {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid months format: %v", err)
		}
		startTime = endTime.AddDate(0, -months, 0)

	case strings.HasSuffix(logRetentionWindow, "y"): // 年
		years, err := strconv.Atoi(strings.TrimSuffix(logRetentionWindow, "y"))
		if err != nil {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid years format: %v", err)
		}
		startTime = endTime.AddDate(-years, 0, 0)

	case strings.Contains(logRetentionWindow, "-"): // 自定义时间段（时间戳）
		parts := strings.Split(logRetentionWindow, "-")
		if len(parts) != 2 {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid timestamp format: expected start-end")
		}
		startTimestamp, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid start timestamp: %v", err)
		}
		endTimestamp, err := strconv.ParseInt(parts[1], 10, 64)
		if err != nil {
			return time.Time{}, time.Time{}, fmt.Errorf("invalid end timestamp: %v", err)
		}
		startTime = time.Unix(startTimestamp, 0)
		endTime = time.Unix(endTimestamp, 0)

	default:
		return time.Time{}, time.Time{}, fmt.Errorf("invalid log retention window format: %s", logRetentionWindow)
	}

	return startTime, endTime, nil
}
